﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Sfs2X;
using Sfs2X.Core;
using Sfs2X.Entities;
using Sfs2X.Requests;
using Sfs2X.Logging;
using Sfs2X.Entities.Data;

public class GUIConnect : MonoBehaviour
{

    public GUIText status;

    private SmartFox sfConnectObj;
    //private SmartFoxState sfConnectState = SmartFoxState.Offline;
    private string userName = "Enter username";
    private string password = "";

    private string loginError;
    private string sfStatus;

    void Awake()
    {
        //Application.runInBackground = true;
        CreateConnectObject();
    }

    // Use this for initialization
    void Start()
    {
        InvokeRepeating("Connect", 1, 5);
    }

    // Update is called once per frame
    void Update()
    {
    }

    void FixedUpdate()
    {
        sfConnectObj.ProcessEvents();
    }

    void OnGUI()
    {
        userName = GUI.TextField(new Rect(250, 140, 200, 20), userName, 25);
    }

    void CreateConnectObject()
    {
        // Create connect object
        if (SmartFoxConnection.IsInitialized)
        {
            sfConnectObj = SmartFoxConnection.Connection;
        }
        else
        {
            sfConnectObj = new SmartFox(true);
        }
        Debug.LogWarning("API Version: " + sfConnectObj.Version);

        // Register callback delegate
        sfConnectObj.AddEventListener(SFSEvent.CONNECTION, OnConnection);
        sfConnectObj.AddEventListener(SFSEvent.CONNECTION_LOST, OnConnectionLost);
        sfConnectObj.AddEventListener(SFSEvent.LOGIN, OnLogin);
        sfConnectObj.AddEventListener(SFSEvent.LOGIN_ERROR, OnLoginError);
        sfConnectObj.AddEventListener(SFSEvent.LOGOUT, OnLogout);
        sfConnectObj.AddEventListener(SFSEvent.USER_EXIT_ROOM, OnExitRoom);
        sfConnectObj.AddEventListener(SFSEvent.ROOM_JOIN, OnEnterRoom);
        sfConnectObj.AddEventListener(SFSEvent.EXTENSION_RESPONSE, OnExtensionResponse);
    }

    void Connect()
    {
        Debug.Log("Trying to connect...");
        status.text = "Trying to connect...";
        sfConnectObj.Connect(ServerDefine.SERVER_NAME, ServerDefine.SERVER_PORT);
    }

    void Login()
    {
        //if (userName.Equals("")) {
        //    guiText.text = "Enter your name";
        //    return;
        //}
        status.text = "Trying to login...";
        if (sfConnectObj.IsConnected && sfConnectObj.MySelf == null)
        {
            sfConnectObj.Send(new LoginRequest(userName, "", ServerDefine.ZONE));
        }
        else
        {
            status.text = "Joining room...";
            RequestGame();
        }
    }

    void RequestGame()
    {
        Debug.Log("request game");
        //sfConnectObj.Send(new LeaveRoomRequest());
        SmartFoxConnection.SendReadyMsg(new SFSObject());
    }

    // HANDLE CONNECT EVENT

    void OnConnection(BaseEvent evt)
    {
        bool success = (bool)evt.Params[MySFSParams.PARAM_SUCCESS];
        string error = (string)evt.Params[MySFSParams.PARAM_ERR_MGS];

        Debug.Log("On Connection callback got: " + success + " (error : <" + error + ">)");

        if (success)
        {
            CancelInvoke();
            //sfConnectState = SmartFoxState.Connected;
            SmartFoxConnection.Connection = sfConnectObj;

            sfStatus = "Connection successful!";
            Debug.Log("TV.Vinh Connection successful!");
            status.text = "Connection successful!";
        }
        else
        {
            sfStatus = "Can't connect to server!";
            Debug.Log("TV.Vinh Can't connect to server!");
            status.text = sfStatus;
        }
    }

    void OnConnectionLost(BaseEvent evt)
    {
        sfStatus = "Connection was lost, Reason: " + (string)evt.Params[MySFSParams.PARAM_REASON];
        status.text = sfStatus;
        InvokeRepeating("Connect", 1, 5);
    }

    void OnLogin(BaseEvent evt)
    {
        // In v1, userName = deviceName
        // in case username conflict, we random a name for user
        //userName = SystemInfo.deviceName;

        Debug.Log("TV.Vinh User: " + userName + " has successful loged in");
        status.text = userName + " has successful loged in";
    }

    void OnLoginError(BaseEvent evt)
    {
        string error = (string)evt.Params[MySFSParams.PARAM_ERR_MGS];
        Debug.Log("TV.Vinh Login error: " + error);
        status.text = "Login error";
    }


    void OnLogout(BaseEvent evt)
    {
        Debug.Log("TV.Vinh User: user has loged out");
    }

    void OnExitRoom(BaseEvent evt)
    {
        Debug.Log("exit room");
    }

    void OnEnterRoom(BaseEvent evt)
    {
        Debug.Log("TV.Vinh User: " + sfConnectObj.MySelf.Name + " has joined room: " + sfConnectObj.LastJoinedRoom.Name);
    }

    void OnExtensionResponse(BaseEvent evt)
    {
        Debug.Log("TV.Vinh User: extension response arrived");
        string cmd = evt.Params[MySFSParams.PARAM_CMD] as string;
        SFSObject dataObject = evt.Params[MySFSParams.PARAM_DATA] as SFSObject;

        switch (cmd)
        {

            // wait for another player | player create room
            case "wait":
                UnregisterSFSSceneCallbacks();
                Application.LoadLevel("Waiting");
                break;

            case "getReady":
                SmartFoxConnection.PersistentData = dataObject;
                UnregisterSFSSceneCallbacks();
                Application.LoadLevel("StandBy");
                break;
        }
    }

    private void UnregisterSFSSceneCallbacks()
    {
        // This should be called when switching scenes, so callbacks from the backend do not trigger code in this scene
        sfConnectObj.RemoveAllEventListeners();
    }

    void OnDestroy()
    {
        UnregisterSFSSceneCallbacks();
    }
}
